package mushystuff.dtb.core.model;

import java.util.Date;
import java.util.SortedSet;
import java.util.TreeSet;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.hibernate.annotations.Sort;
import org.hibernate.annotations.SortType;
import org.hibernate.annotations.Where;

@Entity
public class Sprint extends PersistableBean implements Comparable<Sprint> {

    private String name;
    
    private String goal;

    private SortedSet<UserStory> backlog = new TreeSet<UserStory>();
    
    private SortedSet<Task> unplannedTasks = new TreeSet<Task>();

    private Date start = new Date();

    private Date demo = new Date();

    private Product product;

    public Sprint() {
        super();
    }

    @Column(nullable = false)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Column(nullable = false)
    public String getGoal() {
        return goal;
    }

    public void setGoal(final String aGoal) {
        goal = aGoal;
    }

    @OneToMany(cascade=CascadeType.PERSIST)
    @Sort(type = SortType.NATURAL)
    public SortedSet<UserStory> getBacklog() {
        return backlog;
    }

    protected void setBacklog(final SortedSet<UserStory> aBacklog) {
        this.backlog = aBacklog;
    }

    @OneToMany
    @Sort(type = SortType.NATURAL)
    @Where(clause="assignedUserStory_id is null")
    public SortedSet<Task> getUnplannedTasks() {
		return unplannedTasks;
	}

	public void setUnplannedTasks(SortedSet<Task> unplannedTasks) {
		this.unplannedTasks = unplannedTasks;
	}

	public Date getStart() {
        return start;
    }

    public void setStart(final Date aStart) {
        start = aStart;
    }

    public Date getDemo() {
        return demo;
    }

    public void setDemo(final Date aDemo) {
        demo = aDemo;
    }

    @ManyToOne(optional = false)
    public Product getProduct() {
        return product;
    }

    public void setProduct(Product product) {
        this.product = product;
    }

    @Override
    public int compareTo(Sprint arg0) {
        return getGoal().compareTo(arg0.getGoal());
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (obj == this) {
            return true;
        }
        if (obj.getClass() != getClass()) {
            return false;
        }
        Sprint rhs = (Sprint) obj;
        return new EqualsBuilder().append(goal, rhs.goal).append(product,
                rhs.product).isEquals();
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder(61, 7).append(goal).append(product)
                .toHashCode();
    }

    @Override
    public String toString() {
        return new ToStringBuilder(this).append("goal", goal).append("start",
                start).append("demo", demo).append("product", product).append(
                "backlog.size", backlog.size()).toString();
    }

}
